/**
  ******************************************************************************
  * @file    table.c
  * @author  OneSeventyFour
  * @version V1. 2. 0
  * @date    08-August-2011
  * @brief   Main table drivers
  ******************************************************************************
  */  

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include <stdio.h>
 int primaryAll[16][4];
 int primaryActual[8][8];
 int primaryRed[8][8];
 int primaryGrn[8][8];
 int primaryBlu[8][8];
 int mode;
 uint16_t redSerial = GPIO_Pin_3;
 uint16_t greenSerial = GPIO_Pin_2;
 uint16_t blueSerial = GPIO_Pin_1;
 uint16_t gndSerial = GPIO_Pin_5;
 uint16_t rgbClock = GPIO_Pin_7;
 uint16_t gndClock = GPIO_Pin_8;
 uint16_t rgbLatch = GPIO_Pin_6;
 uint16_t gndLatch = GPIO_Pin_9;
 uint16_t outEnable = GPIO_Pin_4;

void initialize(){

            
    int clocks=0;
    int ints=0;
    int clup=0;
    int fire=0;
    int color=1; 
    int mode=2; //Static mode=2
     
        primaryAll[0][0]=0UL;
        primaryAll[1][0]=1UL;
        primaryAll[2][0]=7UL;
        primaryAll[3][0]=7UL;
        primaryAll[4][0]=7UL;
        primaryAll[5][0]=7UL;
        primaryAll[6][0]=7UL;
        primaryAll[7][0]=7UL;
        primaryAll[8][0]=7UL;
        primaryAll[9][0]=7UL;
        primaryAll[10][0]=7UL;
        primaryAll[11][0]=7UL;
        primaryAll[12][0]=7UL;
        primaryAll[13][0]=7UL;
        primaryAll[14][0]=7UL;
        primaryAll[15][0]=0UL;

           primaryAll[0][1]=0UL;
        primaryAll[1][1]=1UL;
        primaryAll[2][1]=7UL;
        primaryAll[3][1]=7UL;
        primaryAll[4][1]=7UL;
        primaryAll[5][1]=7UL;
        primaryAll[6][1]=7UL;
        primaryAll[7][1]=7UL;
        primaryAll[8][1]=7UL;
        primaryAll[9][1]=7UL;
        primaryAll[10][1]=7UL;
        primaryAll[11][1]=7UL;
        primaryAll[12][1]=7UL;
        primaryAll[13][1]=7UL;
        primaryAll[14][1]=7UL;
        primaryAll[15][1]=0UL;  

          primaryAll[0][2]=0UL;
        primaryAll[1][2]=1UL;
        primaryAll[2][2]=7UL;
        primaryAll[3][2]=7UL;
        primaryAll[4][2]=7UL;
        primaryAll[5][2]=7UL;
        primaryAll[6][2]=7UL;
        primaryAll[7][2]=7UL;
        primaryAll[8][2]=7UL;
        primaryAll[9][2]=7UL;
        primaryAll[10][2]=7UL;
        primaryAll[11][2]=7UL;
        primaryAll[12][2]=7UL;
        primaryAll[13][2]=7UL;
        primaryAll[14][2]=7UL;
        primaryAll[15][2]=0UL;

         primaryAll[0][3]=0UL;
        primaryAll[1][3]=1UL;
        primaryAll[2][3]=7UL;
        primaryAll[3][3]=7UL;
        primaryAll[4][3]=7UL;
        primaryAll[5][3]=7UL;
        primaryAll[6][3]=7UL;
        primaryAll[7][3]=7UL;
        primaryAll[8][3]=7UL;
        primaryAll[9][3]=7UL;
        primaryAll[10][3]=7UL;
        primaryAll[11][3]=7UL;
        primaryAll[12][3]=7UL;
        primaryAll[13][3]=7UL;
        primaryAll[14][3]=7UL;
        primaryAll[15][3]=0UL;

}
/*
 Split Colors takes the 16x4 composite matrix and decodes the color digit.
 We can use logical OR with the whole binary thing to eliminate the need for an intense switch/ifelse statement. 
 While populating the 8x8 "actual" (By actual i mean how it will actually be fed into the shift registers) color arrays, we
 will also populate the primaryActual array, which is used later to determine whether to trigger the grounding register for a row sweep. 


*/
void splitColors(){
int i=0;
int t=0;
int currentActual=0;// Synthetic for referencing a 16x4 as an 8x8.. mainly to chop the 16 in half. Only changed on even increments... duh. 
//SIGNAL BITS
// 000
// RGB
//0-OFF 1-B; 2-G; 3-GB; 4-R;5-RB; 6-RG; 7-RGB
     for(i=0;i<16;i++){
         for(t=0;t<0;t++){
           if(primaryAll[i][t] | 3 == 7){
                if(i%2==0){
                    currentActual=i/2;
                       primaryRed[currentActual][t*2]=1;
                    primaryActual[currentActual][t*2]= primaryAll[i][t];
                }else{
                    primaryRed[currentActual][(t*2)+1]=1;
                    primaryActual[currentActual][(t*2)+1]= primaryAll[i][t];
                }
           }
           if(primaryAll[i][t] | 5 == 7){
                    if(i%2==0){
                    currentActual=i/2;
                       primaryGrn[currentActual][t*2]=1;
                    primaryActual[currentActual][t*2]= primaryAll[i][t];
                }else{
                    primaryGrn[currentActual][(t*2)+1]=1;
                    primaryActual[currentActual][(t*2)+1]= primaryAll[i][t];
                }
           }
           if(primaryAll[i][t] | 6 == 7){
                if(i%2==0){
                    currentActual=i/2;
                       primaryBlu[currentActual][t*2]=1;
                    primaryActual[currentActual][t*2]= primaryAll[i][t];

                }else{
                    primaryBlu[currentActual][(t*2)+1]=1;
                    primaryActual[currentActual][(t*2)+1]= primaryAll[i][t];
                }
           }
        }
     }
}

void shiftMap(int type){
}

void createRows(){
  int redRows[8];
  int greenRows[8];
  int blueRows[8];
  int i,t=0;
   for(i=0;i<8;i++){
           for(t=0;t<8;t++){
             // 
             redRows[i] |= primaryRed[i][t]<<t;
             greenRows[i] |= primaryGrn[i][t]<<t;
             blueRows[i] |= primaryBlu[i][t]<<t;
        }
   }
}

void fillRegisters(int red[],int green[],int blue[]){
int i,t=0;
int focus=1;
     for(i=0;i<8;i++){//Sweeping gnd channels 

         for(t=0;t<8;t++){ // Sweeping RGB channels. For each sweep activation, also sweep the gnd while RGN is active
              GPIO_ResetBits(GPIOA,rgbClock);//Clock Low
             if((red[i] & 1UL<<t) > 0){
                GPIO_SetBits(GPIOA,redSerial);
                 }else{
                GPIO_ResetBits(GPIOA,redSerial);
                 }
            if((green[i] & 1UL<<t) > 0){
                GPIO_SetBits(GPIOA,greenSerial);
                 }else{
                GPIO_ResetBits(GPIOA,greenSerial);
                 }
            if((blue[i] & 1UL<<t) > 0){
                GPIO_SetBits(GPIOA,blueSerial);
                 }else{
                GPIO_ResetBits(GPIOA,blueSerial);
                 }            
            }
            GPIO_SetBits(GPIOA,rgbClock);    //Clock High
     }                                                     
}

int main(void)
{

    GPIO_InitTypeDef GPIO_InitStructure; 
    //RCC_ClocksTypeDef RCC_ClockFreq; 
 

     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    GPIO_InitStructure.GPIO_Pin = gndClock | gndLatch | redSerial | greenSerial | blueSerial | outEnable | rgbLatch | rgbClock | GPIO_Pin_8 | GPIO_Pin_9; 
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; 
      GPIO_Init(GPIOA, &GPIO_InitStructure); 


       
       GPIO_ResetBits(GPIOA,outEnable);
       GPIO_SetBits(GPIOA,GPIO_Pin_8 | GPIO_Pin_9);

       initialize()

  if(mode==1){
  while (1)
  {
       fire = rand() % 13 + 1;
       clocks++;
       if(clocks % 100000 == 0){
       //-----------------------Clock strike
       switch(fire){
        case 1:
        //fire=0;    //Lock
         GPIO_SetBits(GPIOA,blueSerial);
           break;
        case 2:
          GPIO_SetBits(GPIOA,greenSerial);
           break;
        case 3:
          GPIO_SetBits(GPIOA,redSerial);
           break;
        case 4:
          GPIO_SetBits(GPIOA, greenSerial | blueSerial);
           break;
        case 5:
         GPIO_SetBits(GPIOA, greenSerial | redSerial);
           break;
        case 6:
          GPIO_SetBits(GPIOA, greenSerial | redSerial | blueSerial);
           break;
        case 7:
           GPIO_SetBits(GPIOA,blueSerial);
           break;
        case 8:
           GPIO_SetBits(GPIOA,blueSerial);
           break;
        default:
          
           break;
        }
        fire++ ;
             if(clup==1){
          // Clock active strike
            GPIO_SetBits(GPIOA,rgbLatch|rgbClock);
              clup=0;
          }else{
            clup=1; 
            GPIO_ResetBits(GPIOA,rgbLatch|rgbClock);
          }// Clock active strike
        GPIO_ResetBits(GPIOA,blueSerial | greenSerial | redSerial);
        //-----------------------Clock strike
       }

       if(clocks % 100000 == 0){
       //-----GNDCLOCK
               ints++;
                  GPIO_SetBits(GPIOA,gndClock | gndLatch );
            if(ints == 7){
                  GPIO_SetBits(GPIOA,gndSerial);
                  ints=0;
            }else{ 
                GPIO_ResetBits(GPIOA,gndSerial);
                  
            }
                GPIO_ResetBits(GPIOA,gndClock | gndLatch);
       //-----GNDCLOCK
       }

  }
  }
  
  if(mode==2){
   splitColors();
   createRows();
   fillRegisters(redRows,greenRows,blueRows);
   
   while(0){
        clocks++;
       if(clocks % 100000 == 0){
       //-----GNDCLOCK
               ints++;
                  GPIO_SetBits(GPIOA,gndClock | gndLatch );
            if(ints == 7){
                  GPIO_SetBits(GPIOA,gndSerial);
                  ints=0;
            }else{ 
                GPIO_ResetBits(GPIOA,gndSerial);
                  
            }
            GPIO_ResetBits(GPIOA,gndClock | gndLatch);
       //-----GNDCLOCK
       }
        
   }    

   }
 


  
  
}